package com.zhou.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author lang.zhou
 * @date 2022/5/6 9:46
 */
public class ObjectUtil {


    public static <T> T nvl(T a,T b){
        return a == null ? b : a;
    }

    public static <T> T clone(Object o,Class<T> t){
        return JSONObject.parseObject(JSON.toJSONString(o),t);
    }
    public static Map<String,Object> cloneMap(Map<?,?> o){
        return JSONObject.parseObject(JSON.toJSONString(o));
    }

    public static JSONObject bean2Map(Object bean){
        return JSONObject.parseObject(JSON.toJSONString(bean));
    }

    public static <T> List<T> cloneList(List<?> o, Class<T> t){
        return JSONObject.parseArray(JSON.toJSONString(o),t);
    }

    /**
     * 深拷贝(序列化与反序列化实现)
     * @param src 源对象
     * @return 拷贝对象
     */
    @SneakyThrows
    @SuppressWarnings("unchecked")
    public static <T> T deepClone(T src) {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(src);
        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
        ObjectInputStream in = new ObjectInputStream(byteIn);
        return (T) in.readObject();
    }

    public static boolean isEmpty(Object o){
        if(o==null){
            return true;
        }
        if(o instanceof String){
            return StringTool.isBlank(o.toString());
        }
        if(o instanceof Collection){
            return ((Collection<?>) o).isEmpty();
        }
        if(o instanceof Map){
            return ((Map<?,?>) o).isEmpty();
        }
        if(o.getClass().isArray()){
            return ((Object[])o).length==0;
        }
        return false;
    }
    public static boolean isNotEmpty(Object o){
        return !isEmpty(o);
    }

    public static boolean hasEmpty(Object... o){
        for (Object s : o) {
            if(isEmpty(s)){
                return true;
            }
        }
        return false;
    }

    public static boolean allEmpty(Object... o){
        for (Object s : o) {
            if(!isEmpty(s)){
                return false;
            }
        }
        return true;
    }

    public static boolean noEmpty(Object... o){
        return !hasEmpty(o);
    }
    public static Boolean saveToBoolean(Object o,Boolean dv){
        try{
            if (o == null) {
                return dv;
            }else if(o instanceof Boolean){
                return (Boolean) o;
            }else if(o instanceof String){
                return Boolean.valueOf((String) o);
            }
            return dv;
        }catch (Exception e){
            return dv;
        }
    }
}
